Skip to content

Add Header, Claim, and Method value sources to WolverineParameterAttribute#2369

Merged
jeremydmiller merged 1 commit intomainfrom
custom-aggregate-id-resolution
Mar 29, 2026
Merged

Add Header, Claim, and Method value sources to WolverineParameterAttribute#2369
jeremydmiller merged 1 commit intomainfrom
custom-aggregate-id-resolution

Conversation

@jeremydmiller
Copy link
Copy Markdown
Member

Summary

Closes #2351

Extends WolverineParameterAttribute (used by [Aggregate], [WriteAggregate], [ReadAggregate], etc.) with three new ValueSource options for resolving parameter values beyond route arguments and request body properties:

  • ValueSource.Header — Resolve from HTTP request headers or Envelope.Headers in message handlers
  • ValueSource.Claim — Resolve from ClaimsPrincipal claims (HTTP only, throws in handler context)
  • ValueSource.Method — Resolve from the return value of a named static method on the handler/endpoint class, with method injection for its parameters

Convenience properties

// Instead of: [Aggregate(ValueSource = ValueSource.Header, ArgumentName = "X-Tenant-Id")]
[Aggregate(FromHeader = "X-Tenant-Id")]
[Aggregate(FromClaim = "tenant-id")]
[Aggregate(FromMethod = "ResolveId")]
[Aggregate(FromRoute = "orderId")]

Key use case — custom aggregate ID from claims

public static class UpdateConfigEndpoint
{
    public static Guid ResolveId(ClaimsPrincipal user) =>
        Config.CompositeId(user.FindFirst("tenant")?.Value);

    [WolverinePost("/config/update")]
    public static ConfigUpdated Handle(
        UpdateConfig command,
        [Aggregate(FromMethod = "ResolveId")] Config config) => new();
}

Files changed

File Change
ModifyChainAttribute.cs Added Header, Claim, Method to ValueSource enum
WolverineParameterAttribute.cs Added FromHeader, FromRoute, FromClaim, FromMethod properties
Envelope.cs Added TryGetHeader() helper
ReadEnvelopeHeaderFrame.cs New — codegen frame for envelope header reading
HandlerChain.cs Extended TryFindVariable() for Header, Claim (throws), Method
HttpChain.ApiDescription.cs Extended TryFindVariable() for Header, Claim, Method
ReadClaimFrame.cs New — codegen frame for claim reading
Docs: marten.md, middleware.md New "Custom Identity Resolution" and "Parameter Value Sources" sections

Test plan

  • 18 new handler-level unit tests (Header string/int/Guid, Claim throws, Method discovery/base type/not found, convenience properties)
  • 13 new HTTP integration tests (Header string/int/Guid/missing, Claim string/int/Guid/missing, Method Guid/string/default)
  • All 1209 CoreTests pass (0 failures)
  • All 553 HTTP tests pass (0 failures)

🤖 Generated with Claude Code

…ibute

Extends the parameter resolution system used by [Aggregate],
[WriteAggregate], and other WolverineParameterAttribute subclasses
with three new ValueSource options:

- Header: resolve from HTTP request headers or Envelope.Headers
- Claim: resolve from ClaimsPrincipal claims (HTTP only)
- Method: resolve from a static method on the handler/endpoint class

Also adds convenience properties (FromHeader, FromRoute, FromClaim,
FromMethod) for cleaner attribute syntax, and Envelope.TryGetHeader()
helper for null-safe header access without dictionary allocation.

Closes #2351

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Support Custom Aggregate ID Resolution in HTTP Aggregate Workflow

1 participant